/***************************************************************************************************
Universidad del Valle de Guatemala
Algoritmos y estructuras de datos
Karen Tojin   08091
Fecha: 23 de Julio de 2009
Hoja de Trabajo No. 2
Descricion: Programa que simula un parqueo, con el uso de pilas y dos diferentes implementaciones
****************************************************************************************************/

/**
 *
 * @author karenAndy
 */
public class ParquearStackLista<Type> implements InterfazParqueo {

    protected int espacioEnUso,disponibles; // tamaño de la lista y elementos disponibles
    protected Nodo<Type> head; // ref. al primer elemento
    private final int max=10; //tamaño máximo de la lista

    public ParquearStackLista()
    // post: genera una lista vacía
    {
        head = null;
        espacioEnUso = 0;
        disponibles = max;
    }

    public void Push(Object newElement) throws ParqueoLlenoException {
        // post: el nuevo elemento es agregado al principio de la lista
        
        // el nuevo elemento es ahora la cabeza de la lista
        if(this.Full())
            throw new ParqueoLlenoException("El parqueo esta lleno, espere a que salga un automovil");
        else{
            head = new Nodo<Type>((Type) newElement,head);
            espacioEnUso++;
            disponibles--;
        }
    }

    public Object Pop() throws ParqueoVacioException {
        // pre: la lista no está vacía
        // post: quita y devuelve el último elemento que ingresó a la lista
        if(this.Empty())
            throw new ParqueoVacioException("El parqueo esta vacio");
        else{
            Nodo<Type> temp = head;
            head = head.next(); //mueve la referencia de la cabeza de la lista al siguiente elemento
            espacioEnUso--;
            disponibles++;
            return temp.value();
        }
    }

    public Object Peek() throws ParqueoVacioException {
        // pre: la lista no está vacía
        // post: devuelve el último valor ingresado a la lista
        if(this.Empty())
            throw new ParqueoVacioException("El parqueo esta vacio");
        else
            return head.value();
    }

    //This Method can be in the abstract class
    public boolean Empty() {
        //post: devuelve true si la lista está vacía
        if(disponibles==max)
            return true;
        //assert this.Empty();
        return false;
    }

    //This Method can be in the abstract class
    public boolean Full(){
        //post: devuelve true si la lista está llena
        if(disponibles==0)
            return true;
        //assert this.Full();
        return false;
    }

    //This Method can be in the abstract class
    public int Size() {
        //post: devuelve el tamaño de la lista
        /*int espacios=max-disponibles;
        boolean check=false;
        if(espacios==espacioEnUso)
            check = true;
        assert check;*/
        
        return espacioEnUso;
    }
    
    public boolean BuscarAuto(Object elementSearch)throws NoEncontradoException{
        // pre: el elemento buscado no es null
        // post: devuelve true si sí se encontró el elemento
        Nodo<Type> finger = head;
        while (finger != null && !finger.value().equals(elementSearch))
        {
            finger = finger.next();
        }
        return finger != null;
    }

    @Override
    public String toString(){
        // post: devuelve la cadena con los elementos de la lista
        String MostrarElementos=".::Elementos del Parqueo::.\n";
        Nodo<Type> finger = head;
        while (finger != null)
        {
            MostrarElementos +=("  "+finger.value()+"\n");
            finger = finger.next();
        }
        String cantElementos = MostrarElementos+ "\nTotal espacios " + (max-disponibles);
        return cantElementos;
    }
}
